package com.example.lotterysystem.service.activitystatus.impl;

import com.example.lotterysystem.common.errorcode.ServiceErrorCodeConstants;
import com.example.lotterysystem.common.exception.ServiceException;
import com.example.lotterysystem.service.ActivityService;
import com.example.lotterysystem.service.activitystatus.ActivityStatusManager;
import com.example.lotterysystem.service.activitystatus.operator.AbstractActivityOperator;
import com.example.lotterysystem.service.dto.ConvertActivityStatusDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.ConnectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.sql.Connection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import static com.example.lotterysystem.common.config.DirectRabbitConfig.QUEUE_NAME;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Spider-Man
 * Date: 2025-09-15
 * Time: 10:10
 */
@Component

public class ActivityStatusManagerImpl implements ActivityStatusManager {

    //日志配置
    private static final Logger logger = LoggerFactory.getLogger(ActivityStatusManagerImpl.class);

    @Autowired
    private ActivityService activityService;
    /**
     * key: 实现AbstractActivityOperator这个抽象类的名称
     *
     * value: 具体的一个对象
     */

    @Autowired
    private final Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();

    @Override
    @Transactional(rollbackFor = Exception.class) //事务,遇到异常则会回滚数据
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        /*状态扭转有依赖性,导致代码维护性差*/

        if(CollectionUtils.isEmpty(operatorMap)) {
            logger.warn("operatorMap为空");
        }

        //map<String,AbstractActivityOperator>
        Map<String,AbstractActivityOperator> currMap = new HashMap<>(operatorMap);
        Boolean update = false;
        //1.处理:人员, 奖品
        update = processConvertStatus(convertActivityStatusDTO,currMap,1);
        //2.处理:活动
        update = processConvertStatus(convertActivityStatusDTO,currMap,2) || update;

        //更新缓存
        if(update) {
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }
    }

    @Override
    public void rollbackHandlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        //活动,奖品,人员 三个状态都需要回滚
        //原因: 因为回滚的时候需要
        for (AbstractActivityOperator operator : operatorMap.values()) {
            operator.convert(convertActivityStatusDTO);//直接进行转换就可以
        }
        //回滚完成之后,进行缓存数据更新
        activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
    }


    /**
     * 扭转状态
     * @param convertActivityStatusDTO
     * @param currMap
     * @param sequence
     * @return
     */

    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> currMap,
                                         int sequence) {
        Boolean update = false;
        //1. 从currMap或获取到单个AbstractActivityOperator的内容
        Iterator<Map.Entry<String,AbstractActivityOperator>> iterator = currMap.entrySet().iterator();
        while(iterator.hasNext()) {
            AbstractActivityOperator operator = iterator.next().getValue(); //获取到需要扭转的对象.
            //Operator 是否需要进行转换,  sequence = 1 时才需要流转, 或者
            if(operator.sequence() != sequence //
                    || !operator.needConvert(convertActivityStatusDTO)) {
                continue; //当前对象不需要转换
            }
            //需要转换:转换
           if(!operator.convert(convertActivityStatusDTO)) {
               logger.error("{}转换失败!",operator.getClass().getName());
               throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
           }
           //删除当前获取到的Operator
           iterator.remove();
           update = true;
        }
        //返回
        return update;
    }
}
